home *** CD-ROM | disk | FTP | other *** search
/ United Public Domain Gold 2 / United Public Domain Gold 2.iso / utilities / pu722.dms / pu722.adf / 60Hz.Asm < prev    next >
Assembly Source File  |  1994-03-20  |  25KB  |  1,029 lines

  1. * SOS *
  2. ;========================================================================
  3. ;60Hz emulator (PAL-NTSC) V1.04 by P. de Boer in 1991
  4. ;
  5. ;The program was inspired by Power Utility from Amicon and
  6. ;BootPAL/BootNTSC by Nico Francois. Thanks !
  7. ;
  8. ;my monitor synchronizes from 47.5Hz to 65Hz
  9. ;when VBI frequency is 55Hz then the monitor switches.
  10. ;
  11. ;========================================================================
  12. ;Options:
  13. ;Press : <LEFT-ALT>+<LEFT-SHIFT>+<CTRL> and :
  14. ;
  15. ; ESC - To kill the emulator
  16. ; 1 - Toggle color bar
  17. ; 2 - ?
  18. ; 3 - Add ± one line to timer buffer
  19. ; 4 - Sub ± one line to timer buffer
  20. ; 5 - Add one line to total of rasterlines (decreases VBI frequenzy)
  21. ; 6 - Sub one line from total of rasterlines (increases VBI frequenzy)
  22. ; 7 - Add one line to end of display
  23. ; 8 - Sub one line from end of display
  24. ; 9 - Default values
  25. ; 0 - Toggle between 50Hz and 60Hz
  26. ;
  27. ;========================================================================
  28. ;Now some stuff we need !
  29. ;========================================================================
  30.  
  31.             RSRESET        ;little structure for my flags
  32. Flag_60Hz        RS.B    1
  33. Flag_Color        RS.B    1
  34. Flag_OverScan        RS.B    1
  35. Flag_Timing        RS.B    1
  36. Flag_Enable        RS.B    1
  37. Flag_FatAgnus        RS.B    1
  38. Flag_Resident        RS.B    1
  39.  
  40. NULL            EQU    0
  41.  
  42. is_data            EQU    14    ;some stuff from the system's include
  43. is_code            EQU    18    ;files
  44.  
  45. gb_DisplayFlags        EQU    206    ;graphics
  46. gb_DisplayRows        EQU    212
  47. gb_NormalDisplayRows    EQU    216
  48. VBlankFrequency        EQU    530
  49.  
  50. _LVODisplayAlert    EQU    -90    ;intuition
  51.  
  52. _LVOOpen        EQU    -30    ;dos
  53. _LVOClose        EQU    -36
  54. _LVORead        EQU    -42
  55. _LVOWrite        EQU    -48
  56. _LVOInput        EQU    -54
  57. _LVOOutput        EQU    -60
  58.  
  59. MODE_OLD        EQU    1005    ;dos
  60. MODE_NEW        EQU    1006
  61. PR_CLI            EQU    $AC
  62. PR_MSGPORT        EQU    $5C
  63.  
  64. _LVOAlert        EQU    -108    ;exec
  65. _LVODisable        EQU    -120
  66. _LVOEnable        EQU    -126
  67. _LVOForbid        EQU    -132
  68. _LVOPermit        EQU    -138
  69. _LVOAddIntServer    EQU    -168
  70. _LVORemIntServer    EQU    -174
  71. _LVOAllocMem        EQU    -198
  72. _LVOFreeMem        EQU    -210
  73. _LVOAddPort        EQU    -354
  74. _LVORemPort        EQU    -360
  75. _LVOPutMsg        EQU    -366
  76. _LVOGetMsg        EQU    -372
  77. _LVOFindPort        EQU    -390
  78. _LVOCloseLibrary    EQU    -414
  79. _LVOSumLibrary        EQU    -426
  80. _LVOOpenResource    EQU    -498
  81. _LVOOpenLibrary        EQU    -552
  82. _LVOSumKickData        EQU    -612
  83. _LVOCopyMem        EQU    -624
  84.  
  85. ExecBase        EQU    $4
  86.  
  87. LIBF_CHANGED        EQU    2
  88. LIB_FLAGS        EQU    14
  89.  
  90.             RSRESET        ;node structure
  91. LN            RS.B    0
  92. LN_SUCC            RS.L    1
  93. LN_PRED            RS.L    1
  94. LN_TYPE            RS.B    1
  95. LN_PRI            RS.B    1
  96. LN_NAME            RS.L    1
  97. LN_SIZE            RS.W    0
  98.  
  99. NT_MSGPORT        EQU    4
  100. NT_MESSAGE        EQU    5
  101.  
  102.             RSRESET        ;memlist structure
  103. ML            RS.B    LN_SIZE
  104. ML_NUMENTRIES        RS.W    1
  105. ML_ME            RS.W    0
  106. ML_SIZE            RS.W    0
  107.  
  108.             RSRESET
  109. ME            RS.B    0
  110. ME_REQS            RS.W    0
  111. ME_ADDR            RS.L    1
  112. ME_LENGTH        RS.L    1
  113. ME_SIZE            RS.W    0
  114.  
  115. MEMF_PUBLIC        EQU    1<<0
  116. MEMF_CHIP        EQU    1<<1
  117.  
  118.             RSRESET        ;resident structure
  119. RT            RS.B    0
  120. RT_MATCHWORD        RS.W    1
  121. RT_MATCHTAG        RS.L    1
  122. RT_ENDSKIP        RS.L    1
  123. RT_FLAGS        RS.B    1
  124. RT_VERSION        RS.B    1
  125. RT_TYPE            RS.B    1
  126. RT_PRI            RS.B    1
  127. RT_NAME            RS.L    1
  128. RT_IDSTRING        RS.L    1
  129. RT_INIT            RS.L    1
  130. RT_SIZE            RS.W    0
  131.  
  132. RTC_MATCHWORD        EQU    $4AFC
  133. RTB_COLDSTART        EQU    0
  134. RTF_COLDSTART        EQU    1<<0
  135. RTB_AUTOINIT        EQU    7
  136. RTF_AUTOINIT        EQU    1<<7
  137. RTM_WHEN        EQU    1
  138. RTW_NEVER        EQU    0
  139. RTW_COLDSTART        EQU    1
  140.  
  141. KickMemPtr        EQU    546    ;execbase equ's
  142. KickTagPtr        EQU    550
  143. KickCheckSum        EQU    554    
  144.  
  145. DMACONR            EQU    $002    ;custom chip addresses
  146. VPOSR            EQU    $004
  147. VHPOSR            EQU    $006
  148. VPOSW            EQU    $02A
  149. VHPOSW            EQU    $02C
  150. DIWSTRT            EQU    $08E
  151. DIWSTOP            EQU    $090
  152. DMACON            EQU    $096
  153. COLOR00            EQU    $180
  154. BEAMCON0        EQU    $1DC
  155. CUSTOM            EQU    $DFF000
  156.  
  157. ;========================================================================
  158. CALL        MACRO
  159.         IFC    'EXEC','\1'
  160.         MOVEA.L    (ExecBase).W,A6
  161.         ENDC
  162.         IFNC    'EXEC','\1'
  163.         MOVEA.L    \1Base,A6
  164.         ENDC
  165.         JSR    _LVO\2(A6)
  166.         ENDM
  167.  
  168. OPENLIB        MACRO
  169.         LEA    \1Name(PC),A1
  170.         CLR.L    D0
  171.         CALL    EXEC,OpenLibrary
  172.         MOVE.L    D0,\1Base
  173.         BEQ    \2
  174.         ENDM
  175.  
  176. CLOSELIB    MACRO
  177.         MOVEA.L    \1Base,A1
  178.         CALL    EXEC,CloseLibrary
  179.         ENDM
  180.  
  181. ;========================================================================
  182. ;Here we go !!!
  183. ;========================================================================
  184. InstallEmulator    move.l    a0,a5            ;store pointer to cmd line
  185.         st    Flag_Resident+Flags
  186.  
  187. ;===============================================
  188. CheckAgnus    move.w    $DFF004,d0        ;check what kind of agnus
  189.         and.w    #$2000,d0        ;we got
  190.         beq.s    OldAgnus
  191.         st    Flag_FatAgnus+Flags
  192. OldAgnus
  193. ;===============================================
  194. OpenDosLib    OPENLIB    DOS,NoDOS        ;open dos library
  195.         CALL    DOS,Output        ;get standart output chanel
  196.         move.l    d0,OutHandle        ;store it
  197.         beq.s    .Skip            ;if not available then skip
  198.         move.l    OutHandle(pc),d1
  199.         move.l    #Hello.TXT,d2
  200.         move.l    #Hello.LEN,d3
  201.         CALL    DOS,Write        ;print message
  202. .Skip
  203. ;===============================================
  204. SearchFlagOpt    movea.l    a5,a0            ;search for any flag options
  205. .SearchLoop    move.b    (a0)+,d0
  206.         cmp.b    #$0A,d0            ;jump out of loop if we
  207.         beq.s    Search            ;find a return
  208.         cmp.b    #"?",d0            ;an request for info ?
  209.         beq.s    .PrintSyntax
  210.         ori.b    #$20,d0            ;make lower case (quick &dirty)
  211.         cmp.b    #"a",d0            ;ignore BIG-FAT-Agnus ?
  212.         beq.s    .OverRide
  213.         cmp.b    #"r",d0            ;non resident install ?
  214.         bne.s    .SearchLoop
  215.  
  216. .Resident    SF    Flag_Resident+Flags    ;clear Resident flag
  217.         bra.s    .SearchLoop
  218. .OverRide    SF    Flag_FatAgnus+Flags    ;clear FAT agnus flag
  219.         bra.s    .SearchLoop
  220.  
  221. .PrintSyntax    move.l    #Syntax.TXT,d2        ;Print syntax if we've found
  222.         move.l    #Syntax.LEN,d3        ;an '?'
  223.         bra    PrintMsgAndQuit
  224.  
  225. ;===============================================
  226. Search        movea.l    a5,a0            ;search for install options
  227. .SearchLoop    move.b    (a0),d0
  228.         cmp.b    #"i",d0
  229.         beq.w    InstallNTSC
  230.         cmp.b    #"I",d0
  231.         beq.w    InstallPAL
  232.         ori.b    #$20,d0            ;always lower case
  233.         cmp.b    #"k",d0
  234.         beq.s    Remove
  235.         cmp.b    #$0A,(a0)+
  236.         bne.s    .SearchLoop
  237.         bra.s    InstallNTSC
  238.  
  239. ;===============================================
  240. Remove        lea    MyPortName(PC),a1    ;search emulator msg.port
  241.         CALL    EXEC,FindPort        ;find my port
  242.         tst.l    d0
  243.         bne.s    FoundMyPort
  244.  
  245.         move.l    #Unable.TXT,d2        ;can't find port !
  246.         move.l    #Unable.LEN,d3
  247.         bra.w    PrintMsgAndQuit
  248.  
  249. FoundMyPort    move.l    d0,a0            ;found port
  250.         lea    Message(pc),a1        ;send message to emulator
  251.         move.l    #'KILL',20(a5)        ;kill MSG
  252.         CALL    EXEC,PutMsg        ;to remove itself.
  253.  
  254. Waitting    cmp.l    #'KILL',Message.TXT    ;waiting for return msg
  255.         beq.s    Waitting
  256.  
  257.         tst.l    Message.TXT        ;message = 0 ??
  258.         bne.s    .Error            ;no -> something wrong
  259.  
  260. .Killed        move.l    #Removed.TXT,d2        ;all well, print remove
  261.         move.l    #Removed.LEN,d3        ;message
  262.         bra.w    PrintMsgAndQuit
  263.  
  264. .Error        move.l    #Unable.TXT,d2        ;no -> something went
  265.         move.l    #Unable.LEN,d3        ;wrong
  266.         bra.w    PrintMsgAndQuit
  267.  
  268. ;===============================================
  269. InstallNTSC    sf    Flag_60Hz+Flags        ;install and start NTSC
  270.         bra.s    Install
  271. InstallPAL    st    Flag_60Hz+Flags        ;install and Start PAL
  272. Install        BSR    InstallRomTag        ;install Tag
  273.         bne.s    PrintMsgAndQuit
  274.  
  275. ;===============================================
  276. TagInstalled    jsr    4(a0)            ;Initialize emulator
  277.         beq.s    EmulatorOn
  278.  
  279.         BSR    RemoveRomTag        ;kill romtag if something wrong
  280.  
  281.         move.l    #Failure.TXT,d2
  282.         move.l    #Failure.LEN,d3
  283.         bra.s    PrintMsgAndQuit
  284.  
  285. EmulatorOn    tst.b    Flag_FatAgnus+Flags
  286.         beq.s    .Skip
  287.  
  288.         move.l    #NewAgnus.TXT,d2
  289.         move.l    #NewAgnus.LEN,d3
  290.         move.l    OutHandle(pc),d1
  291.         beq.s    .Skip
  292.         CALL    DOS,Write        ;print agnus message
  293.  
  294. .Skip        tst.b    Flag_Resident+Flags
  295.         bne.s    .Skip2
  296.  
  297.         move.l    #NResident.TXT,d2
  298.         move.l    #NResident.LEN,d3
  299.         move.l    OutHandle(pc),d1
  300.         beq.s    .Skip2
  301.         CALL    DOS,Write        ;print resident message
  302.  
  303. .Skip2        move.l    #Installed.TXT,d2
  304.         move.l    #Installed.LEN,d3
  305.  
  306. ;===============================================
  307. PrintMsgAndQuit    move.l    OutHandle(pc),d1
  308.         beq.s    Einde
  309.         CALL    DOS,Write        ;print message
  310.  
  311. Einde        CLOSELIB    DOS        ;close dos library
  312.  
  313. NoDOS        clr.l    d0
  314.         rts
  315.  
  316. ;========================================================================
  317. Message        DC.L    0            ;message to emulator
  318.         DC.L    0
  319.         DC.B    NT_MESSAGE
  320.         DC.B    0
  321.         DC.L    0
  322.         DC.L    0            ;reply port: geen
  323.         DC.W    Message.LEN
  324. Message.TXT    DC.B    "KILL"
  325. Message.LEN    EQU    *-Message.TXT
  326.  
  327.  
  328. DOSName        DC.B    "dos.library",$0
  329.         EVEN
  330. DOSBase        DC.L    0
  331. CodeMem        DC.L    0
  332. OutHandle    DC.L    0
  333.  
  334. Hello.TXT    DC.B    $9B,"33;1m60Hz Emulator"
  335.         DC.B    $9B,"0m V1.04 by P. de Boer",$0A
  336. Hello.LEN    EQU    *-Hello.TXT
  337.  
  338. Syntax.TXT    DC.B    "This program is shareware, NOT public domain !"
  339.         DC.B    $0A
  340.         DC.B    "Read the .DOC file for more information !"
  341.         DC.B    $0A,$0A
  342.         DC.B    $9B,"1;33mSyntax....:"
  343.         DC.B    $9B,"0m 60Hz <OPTIONS>",$0A
  344.         DC.B    $9B,"1;33mOptions...:",$9B,"0m "
  345.         DC.B    "i   = Install emulator and jump in NTSC mode.",$0A
  346.         DC.B    "            "
  347.         DC.B    "I   = Install emulator and jump in PAL mode.",$0A
  348.         DC.B    "            "
  349.         DC.B    "K/k = Kill emulator !",$0A
  350.         DC.B    $9B,"1;33mAdditional:",$9B,"0m "
  351.         DC.B    "R/r = Install emulator NON-resident in memory",$0A
  352.         DC.B    "            "
  353.         DC.B    "A/a = Ignore BIG FAT-Agnus, i.e. always software"
  354.         DC.B    " emulation",$0A,$0A
  355.         DC.B    "When the emulator is installed, ",$0A
  356.         DC.B    "press <LEFT-ALT>+<LEFT-SHIFT>+<CTRL> and ",$0A
  357.         DC.B    "ESC - To remove the emulator from memory",$0A
  358.         DC.B    "  0 - To toggle between PAL and NTSC",$0A,$0A
  359. Syntax.LEN    EQU    *-Syntax.TXT
  360.  
  361. Already.TXT    DC.B    "60Hz Emulator was already installed !",$0A
  362. Already.LEN    EQU    *-Already.TXT
  363.  
  364. NoMem.TXT    DC.B    "Not enough memory for emulator (I only need "
  365.         DC.B    "±2800 Bytes) !",$0A
  366. NoMem.LEN    EQU    *-NoMem.TXT
  367.  
  368. Installed.TXT    DC.B    "60Hz Emulator installed !",$0A
  369. Installed.LEN    EQU    *-Installed.TXT
  370.  
  371. Removed.TXT    DC.B    "60Hz Emulator removed !",$0A
  372. Removed.LEN    EQU    *-Removed.TXT
  373.  
  374. Unable.TXT    DC.B    "Unable to find Emulator in memory !",$0A
  375. Unable.LEN    EQU    *-Unable.TXT
  376.  
  377. Failure.TXT    DC.B    "Installation failed !",$0A
  378. Failure.LEN    EQU    *-Failure.TXT
  379.  
  380. NewAgnus.TXT    DC.B    "Fantastic, you got a BIG FAT-Agnus !!",$0A
  381. NewAgnus.LEN    EQU    *-NewAgnus.TXT
  382.  
  383. NResident.TXT    DC.B    "Emulator will be gone after reset !",$0A
  384. NResident.LEN    EQU    *-NResident.TXT
  385.  
  386.         EVEN
  387.  
  388. ;========================================================================
  389. InstallRomTag    lea    MyPortName(PC),a1    ;find my port
  390.         CALL    EXEC,FindPort
  391.         tst.l    d0
  392.         beq.s    AllocateMem
  393.  
  394.         move.l    #Already.TXT,d2        ;already installed
  395.         moveq    #Already.LEN,d3
  396.         moveq    #-1,d0
  397.         rts
  398.  
  399. AllocateMem    move.l    #TagCodeLen,d0        ;allocate memory for
  400.         moveq    #MEMF_CHIP,d1        ;emulator
  401.         CALL    EXEC,AllocMem
  402.         tst.l    d0
  403.         bne.s    CopyTagCode
  404.  
  405.         move.l    #NoMem.TXT,d2        ;not enough memory ??
  406.         moveq    #NoMem.LEN,d3
  407.         moveq    #-1,d0
  408.         rts
  409.  
  410. CopyTagCode    movea.l    d0,a5            ;a5 holds address of copy
  411.         lea    TagCode(PC),a0        ;copy code
  412.         movea.l    d0,a1
  413.         move.l    #TagCodeLen,d0
  414.         CALL    EXEC,CopyMem
  415.  
  416.         lea    Flags(pc),a0
  417.         tst.b    Flag_Resident(a0)
  418.         beq.s    InitPort
  419.  
  420.         CALL    EXEC,Forbid        ;shut down system
  421.         CALL    EXEC,Disable
  422.  
  423.         lea    RomTagPtrs-TagCode(a5),a0
  424.         move.l    KickTagPtr(a6),4(a0)
  425.         beq.s    NoTagYet
  426.         bset    #7,4(a0)        ;set bit 31 if tag was set
  427.  
  428. NoTagYet    move.l    a0,KickTagPtr(a6)    ;install my romtag
  429.         lea    MyRomTag-TagCode(a5),a1
  430.         move.l    a1,(a0)
  431.  
  432. InitMemList    lea    MyMemList-TagCode(a5),a1
  433.         move.l    a5,ML_SIZE+ME_ADDR(a1)
  434.         move.l    KickMemPtr(a6),d0
  435.         move.l    d0,LN_SUCC(a1)
  436.         move.l    a1,KickMemPtr(a6)    ;install my memlist
  437.  
  438. InitRomTag    lea    MyRomTag-TagCode(a5),a1
  439.         move.l    a1,RT_MATCHTAG(a1)
  440.         lea    RT_SIZE(a1),a2
  441.         move.l    a2,RT_ENDSKIP(a1)
  442.         lea    ProjectName-TagCode(a5),a2
  443.         move.l    a2,RT_NAME(a1)
  444.         move.l    a5,RT_INIT(a1)
  445.         CALL    EXEC,SumKickData
  446.         move.l    d0,KickCheckSum(a6)    ;recalculate checksum
  447.  
  448. InitPort    lea    MyPortName-TagCode(a5),a0
  449.         lea    MyPort-TagCode(a5),a1
  450.         clr.l    LN_SUCC(a1)
  451.         clr.l    LN_PRED(a1)
  452.         move.l    a0,LN_NAME(a1)
  453.         CALL    EXEC,AddPort        ;add my port
  454.  
  455.         CALL    EXEC,Enable        ;powerup system
  456.         CALL    EXEC,Permit
  457.  
  458. Exit        movea.l    a5,a0            ;pass code address
  459.         clr.l    d0
  460.         rts
  461.  
  462. ;========================================================================
  463. ;This piece of code will be resident in memory !
  464. ;========================================================================
  465.  
  466. TagCode        JMP    InitTagCode(pc)        ;jump table
  467.         JMP    InitEmulator(pc)
  468.  
  469. ;========================================================================
  470. InitTagCode    movem.l    d0-d7/a0-a6,-(SP)    ;this routine
  471.                         ;will be executed
  472.         lea    MyPort(pc),a1        ;in the reset routine
  473.         lea    MyPortName(PC),a0
  474.         clr.l    LN_SUCC(a1)
  475.         clr.l    LN_PRED(a1)
  476.         move.l    a0,LN_NAME(a1)
  477.         CALL    EXEC,AddPort
  478.  
  479.         BSR.S    InitEmulator        ;re-init emulator
  480.  
  481. EndTagCode    movem.l    (SP)+,d0-d7/a0-a6    ;return to kicky
  482.         rts
  483.  
  484. ;========================================================================
  485. InitEmulator    BSR.S    InitStructures
  486.  
  487.         lea    Flags(pc),a0
  488.         sf    Flag_Enable(a0)    ;prevent interrupt
  489.         tst.b    Flag_FatAgnus(a0)
  490.         bne.s    .Skip
  491.         BSR.S    OpenIntLib
  492.         BSR.S    OpenResource
  493.         BNE.S    .Failure
  494. .Skip        BSR    PatchSystem
  495.         BNE.S    .Failure
  496.         BSR    AddServers
  497.  
  498.         clr.l    d0
  499. .Failure    rts
  500.  
  501. ;========================================================================
  502. Alert        clr.l    d0            ;display alert
  503.         moveq    #32,d1
  504.         movea.l    INTBase(pc),a6
  505.         jsr    _LVODisplayAlert(a6)
  506.         rts
  507. ;===============================================
  508. OpenIntLib    lea    INTName(pc),a1
  509.         clr.l    d0
  510.         CALL    EXEC,OpenLibrary
  511.         lea    INTBase(pc),a0
  512.         move.l    d0,(a0)
  513.         bne.s    .Skip
  514.         rts
  515.         move.l    #$04030000,d7        ;software failure
  516.         lea    $FC00D2,a5        ;if intuition.library
  517.         CALL    EXEC,Alert        ;didn't open
  518. .Skip        rts
  519. ;===============================================
  520. InitStructures    lea    TagCode(pc),a0        ;relocate structures !
  521.         move.l    a0,d0
  522.         lea    CIAA_Server(pc),a0
  523.         BSR.S    .InitStruct
  524.         lea    CIAB_Server(pc),a0
  525.         BSR.S    .InitStruct
  526.         lea    VBI_Server(pc),a0
  527. .InitStruct    add.l    d0,LN_NAME(a0)
  528.         add.l    d0,is_data(a0)
  529.         add.l    d0,is_code(a0)
  530.         lea    InitStructures(pc),a0
  531.         move.w    #$4E75,(a0)        ;put RTS at InitStruct
  532.         rts
  533. ;===============================================
  534. OpenResource    lea    CIABName(pc),a1        ;open ciab.resource
  535.         clr.l    d0
  536.         CALL    EXEC,OpenResource
  537.         lea    CIABBase(pc),a0
  538.         move.l    d0,(a0)
  539.         beq.s    .Error
  540.         moveq    #0,d0
  541.         rts
  542. .Error        lea    NoResourceAlert(pc),a0    ;no resource ??
  543.         BSR.W    Alert
  544.         moveq    #-1,d0
  545.         rts
  546.  
  547. ;===============================================
  548. AllocateTimer    move.b    #0,d0            ;timer a interrupt
  549.         lea    CIAB_Server(pc),a1
  550.         move.l    CIABBase(pc),a6
  551.         jsr    -6(a6)            ;set interrupt
  552.         tst.l    d0
  553.         beq.s    .Ok
  554.  
  555. .Error        lea    NoTimerAlert(pc),a0    ;no timer !
  556.         BSR.W    Alert
  557.         moveq    #-1,d0
  558. .Ok        rts
  559.  
  560. ;===============================================
  561. DeAllocateTimer    move.b    #0,d0
  562.         move.l    CIABBase(pc),a6
  563.         jsr    -12(a6)            ;clr interrupt
  564.         rts
  565.  
  566. ;===============================================
  567. AddServers    lea    Flags(pc),a0
  568.         sf    Flag_Enable(a0)
  569.  
  570.         move.w    #$0005,d0        ;vertical blank interrupt
  571.         lea    VBI_Server(pc),a1
  572.         CALL    EXEC,AddIntServer
  573.         move.w    #$0003,d0        ;keyboard interrupt
  574.         lea    CIAA_Server(pc),a1
  575.         CALL    EXEC,AddIntServer
  576.  
  577.         lea    Flags(pc),a0
  578.         st    Flag_Enable(a0)
  579.  
  580.         rts
  581. ;===============================================
  582. PatchSystem    lea    Flags(pc),a0        ;this routine does it !
  583.         tst.b    Flag_60Hz(a0)
  584.         beq.s    Go60
  585.  
  586. ;===============================================
  587. Go50        tst.b    Flag_FatAgnus(a0)    ;put system in PAL mode
  588.         beq.s    .NoFatty
  589.  
  590.         move.w    #$0020,BEAMCON0!CUSTOM    ;very simple if we have a FAT
  591.         bra.s    .Go50            ;Agnus
  592.  
  593. .NoFatty    BSR.S    DeAllocateTimer        ;free timers
  594.  
  595. .Go50        lea    Flags(pc),a0
  596.         sf    Flag_Enable(a0)        ;stop it
  597.  
  598.         lea    GFXName(PC),a1
  599.         clr.l    d0
  600.         CALL    EXEC,OpenLibrary    ;open graphics library
  601.         move.l    d0,a1
  602.         move.w    gb_DisplayFlags(a1),d0    ;adjust display flags
  603.         and.b    #%11111110,d0        ;erase NTSC flag
  604.         or.b    #%00000100,d0        ;set PAL flag
  605.         move.w    d0,gb_DisplayFlags(a1)
  606.         move.w    #256,gb_NormalDisplayRows(a1)
  607.         move.w    #311,gb_DisplayRows(a1)
  608.         or.b    #LIBF_CHANGED,LIB_FLAGS(a1)
  609.         movea.l    a1,a2
  610.         CALL    EXEC,SumLibrary        ;caluclate checksum
  611.         movea.l a2,a1
  612.         CALL    EXEC,CloseLibrary    ;close lib again
  613.         move.b    #50,VBlankFrequency(a6)    ;change EXEC library
  614.         or.b    #LIBF_CHANGED,LIB_FLAGS(a6)
  615.         CALL    EXEC,SumLibrary        ;calculate checksum
  616.         moveq    #0,d0
  617.         rts
  618.  
  619. ;===============================================
  620. Go60        tst.b    Flag_FatAgnus(a0)    ;put system in NTSC mode
  621.         beq.s    .NoFatty
  622.  
  623.         move.w    #$0000,BEAMCON0!CUSTOM    ;to NTSC please
  624.         bra.s    .Go60
  625.  
  626. .NoFatty    BSR    AllocateTimer        ;allocate timers again
  627.         bne.s    .Error            ;not available
  628.  
  629. .Go60        lea    GFXName(PC),a1        ;modify graphics.library
  630.         clr.l    d0
  631.         CALL    EXEC,OpenLibrary
  632.         move.l    d0,a1
  633.         move.w    gb_DisplayFlags(a1),d0
  634.         and.b    #%11111011,d0
  635.         or.b    #%00000001,d0
  636.         move.w    d0,gb_DisplayFlags(a1)
  637.         move.w    #200,gb_NormalDisplayRows(a1)
  638.         move.w    #262,gb_DisplayRows(a1)
  639.         or.b    #LIBF_CHANGED,LIB_FLAGS(a1)
  640.         movea.l    a1,a2
  641.         CALL    EXEC,SumLibrary
  642.         movea.l    a2,a1
  643.         CALL    EXEC,CloseLibrary
  644.         move.b    #60,VBlankFrequency(a6)
  645.         or.b    #LIBF_CHANGED,LIB_FLAGS(a6)
  646.         CALL    EXEC,SumLibrary
  647.  
  648.         lea    Flags(pc),a0
  649.         st    Flag_Enable(a0)        ;start it
  650.         moveq    #0,d0
  651.         rts
  652.  
  653. .Error        lea    Flags(pc),a0
  654.         st    Flag_60Hz(a0)
  655.         sf    Flag_Enable(a0)        ;stop it
  656.         moveq    #-1,d0
  657.         rts
  658.  
  659. ;========================================================================
  660. CIAA_Server_Int    movem.l    d0-d7/a0-a6,-(SP)    ;keyboard interrupt
  661.         st    d1            ;server
  662.         lea    EnterKeys(pc),a0
  663.         move.b    $BFEC01,d5        ;read raw keycode
  664.         not.b    d5
  665.         ror.b    #1,d5
  666.         bmi.s    .NotPressed
  667.         sf    d1
  668. .NotPressed    andi.b    #$7F,d5
  669. .TestCTRL    cmp.b    #$63,d5
  670.         bne.s    .TestSHIFT
  671.         move.b    d1,(a0)        
  672. .TestSHIFT    cmp.b    #$60,d5
  673.         bne.s    .TestALT
  674.         move.b    d1,1(a0)        
  675. .TestALT    cmp.b    #$64,d5
  676.         bne.s    .EndTest
  677.         move.b    d1,2(a0)        
  678. .EndTest    tst.b    d1
  679.         bne.s    CIAA_Return
  680.  
  681. AreWeInControl    tst.l    (a0)
  682.         bne.s    CIAA_Return
  683.         cmp.b    #$45,d5
  684.         beq.s    .Go
  685.         cmp.b    #$0A,d5
  686.         bgt.s    CIAA_Return
  687. .Go        clr.b    $BFEC01            ;kill key-code
  688.         lea    Flags(pc),a5
  689.         BSR    CheckESC
  690.         tst.b    Flag_Enable(a5)
  691.         beq.s    .Skip
  692.         BSR    CheckColor        ;check keys
  693.         BSR    CheckTiming
  694.         BSR    CheckTime
  695.         BSR    CheckStartPos
  696.         BSR    CheckEndPos
  697.         BSR    CheckDefault
  698. .Skip        BSR    Check60Hz
  699. CIAA_Return    movem.l    (SP)+,d0-d7/a0-a6
  700.         DC.W    $003C,$0004
  701.         rts
  702.  
  703. ;========================================================================
  704. VBI_Server_Int    movem.l    d0-d7/a0-a6,-(SP)    ;vertical blank interrupt
  705.  
  706.         BSR    CheckForMSG        ;check for incoming msg
  707.  
  708.         lea    Flags(pc),a0        ;server
  709.         tst.b    Flag_Enable(a0)        ;are we in 60Hz mode ?
  710.         beq.s    .Skip            ;if not then skip
  711.  
  712.         lea    CUSTOM,a0        ;custom chip base
  713.         move.w    DMACONR(a0),d1        ;read DMACON
  714.         move.w    #$0440,DMACON(a0)    ;clear blitpri & blitdma
  715.  
  716.         clr.w    d0
  717.         move.b    VHPOSR(a0),d0        ;read actual beam pos
  718.         neg.w    d0            ;make it negative
  719.         add.w    EndPos(pc),d0        ;add endpos
  720.         mulu    #45,d0            ;multiply with cycle/line
  721.         sub.w    VBITime(pc),d0        ;subtrack buffer time
  722.         move.b    d0,$bfd400        ; Timer A high byte
  723.         lsr.w    #8,d0            ;get low byte
  724.         move.b    d0,$bfd500        ; Timer A low byte
  725.         move.b    #%00011001,$BFDE00    ;load timer-a
  726.  
  727.         andi.w    #$0440,d1        ;reinstall dma again
  728.         ori.w    #$8000,d1
  729.         move.w    d1,DMACON(a0)        ;write it in dmacon
  730.  
  731. .Skip        movem.l    (SP)+,d0-d7/a0-a6
  732.         DC.W    $003C,$0004        ;or.w #$4,SR ;set Z-Flag
  733.         rts
  734.  
  735. ;========================================================================
  736. CIAB_Server_Int    movem.l    d0-d2/a0,-(a7)
  737.         lea    Flags(pc),a0
  738.         tst.b    Flag_Enable(a0)
  739.         beq.s    GetOutOfHere
  740.         lea    CUSTOM,a0        ;get custom base address
  741.         move.w    DMACONR(a0),d2        ;read dma
  742.         move.w    #$0440,DMACON(a0)    ;clear blitpri&blitdma
  743.         move.w    EndPos(pc),d1
  744.         lsl.w    #8,d1
  745.         ori.w    #$D1,d1
  746. StartColor    move.w    #$0505,$1FE(a0)        ;put colorbar if needed
  747.         move.w    EndPos(pc),d0        ;wait for line 'EndPos'
  748. WaitLine    cmp.b    VHPOSR(a0),d0
  749.         bgt.s    WaitLine
  750.         move.w    d1,DIWSTOP(a0)
  751. EndColor    move.w    #$0000,$1FE(a0)
  752.         move.l    StartPos(pc),d1
  753.         move.l    VPOSR(a0),d0        ;prevents shocking
  754.         sub.l    VPOSR(a0),d0        ;of menu bar
  755.         sub.l    d0,d1            ;subtract it from StartPos
  756.         add.l    VPOSR(a0),d1        ;add current beam pos
  757.         move.l    d1,VPOSW(a0)        ;write new beampos
  758.         andi.w    #$0440,d2        ;
  759.         ori.w    #$8000,d2
  760.         move.w    d2,DMACON(a0)        ;enable blitpri&blitdma
  761. GetOutOfHere    movem.l    (a7)+,d0-d2/a0        ;return to system
  762.         rts
  763.  
  764. ;========================================================================
  765. CheckForMSG    lea    MyPort(pc),a0        ;check message port
  766.         CALL    EXEC,GetMsg        ;get message
  767.         tst.l    d0
  768.         beq.s    .NoMSG            ;mmmm.. no message
  769.  
  770.         move.l    d0,a5            ;got message, yeah !
  771.         cmp.l    #"KILL",20(a5)        ;is it a 'KILL' message ??
  772.         beq.s    MSG.Kill
  773.         cmp.l    #"50Hz",20(a5)
  774.         beq.s    MSG.50Hz
  775.         cmp.l    #"60Hz",20(a5)
  776.         beq.s    MSG.60Hz
  777.  
  778. .NoMSG        rts
  779.  
  780. MSG.50Hz    lea    Flags(pc),a0
  781.         tst.b    Flag_60Hz(a0)
  782.         bne.s    .Already50Hz
  783.         st    Flag_60Hz(a0)
  784.         BSR.W    PatchSystem
  785. .Already50Hz    clr.l    20(a5)
  786.         rts
  787.  
  788. MSG.60Hz    lea    Flags(pc),a0
  789.         tst.b    Flag_60Hz(a0)
  790.         beq.s    .Already60Hz
  791.         sf    Flag_60Hz(a0)
  792.         BSR    PatchSystem
  793.         move.l    d0,20(a5)
  794.         rts
  795. .Already60Hz    clr.l    20(a5)
  796.         rts
  797.  
  798. MSG.Kill    BSR    KillEmulator        ;yes? -> kill me (?)
  799.         move.l    d0,20(a5)
  800.         rts
  801.  
  802. ;========================================================================
  803. ;Subroutines for key checking !
  804. ;
  805. ;=======================================
  806. CheckColor    cmp.b    #$01,d5
  807.         bne.s    .NoColorFlag
  808.         lea    EndColor+4(pc),a1
  809.         lea    StartColor+4(pc),a2
  810.         not.b    Flag_Color(a5)
  811.         beq.s    .ColorOff
  812. .ColorOn    move.w    #COLOR00,(a1)
  813.         move.w    #COLOR00,(a2)
  814.         bra.s    .NoColorFlag
  815. .ColorOff    move.w    #$01FE,(a1)
  816.         move.w    #$01FE,(a2)
  817. .NoColorFlag    rts
  818. ;=======================================
  819. CheckTiming    cmp.b    #$02,d5
  820.         bne.s    .NoTimingCheck
  821.         not.b    Flag_Timing(a5)
  822. .NoTimingCheck    rts
  823. ;=======================================
  824. CheckTime    lea    VBITime(pc),a1
  825.         cmp.b    #$03,d5
  826.         beq.s    .NoAdd
  827.         sub.w    #45,(a1)
  828. .NoAdd        cmp.b    #$04,d5
  829.         beq.s    .NoSub
  830.         add.w    #45,(a1)
  831. .NoSub        rts
  832. ;=======================================
  833. CheckStartPos    lea    StartPos(pc),a1
  834.         cmp.b    #$05,d5
  835.         beq.s    .NoAdd
  836.         add.l    #$0100,(a1)
  837. .NoAdd        cmp.b    #$06,d5
  838.         beq.s    .NoSub
  839.         sub.l    #$0100,(a1)
  840. .NoSub        rts
  841. ;=======================================
  842. CheckEndPos    lea    EndPos(pc),a1
  843.         cmp.b    #$07,d5
  844.         beq.s    .NoAdd
  845.         addq.w    #$0001,(a1)
  846. .NoAdd        cmp.b    #$08,d5
  847.         beq.s    .NoSub
  848.         subq.w    #$0001,(a1)
  849. .NoSub        rts
  850. ;=======================================
  851. CheckDefault    cmp.b    #$09,d5
  852.         bne.s    .Skip
  853.         lea    EndPos(pc),a1
  854.         move.w    #$0104,(a1)
  855.         lea    StartPos(pc),a1
  856.         move.l    #$3203,(a1)
  857.         lea    VBITime(pc),a1
  858.         move.w    #8*45,(a1)
  859. .Skip        rts
  860. ;=======================================
  861. Check60Hz    cmp.b    #$0A,d5
  862.         bne.s    .Skip
  863.         not.b    Flag_60Hz(a5)
  864.         BSR    PatchSystem
  865. .Skip        rts
  866. ;=======================================
  867. CheckESC    cmp.b    #$45,d5
  868.         bne.s    .Skip
  869.         BSR.S    KillEmulator
  870. .Skip        rts
  871. ;========================================================================
  872. KillEmulator    CALL    EXEC,Disable
  873.         move.w    #$0005,d0        ;vertical blank interrupt
  874.         lea    VBI_Server(pc),a1
  875.         CALL    EXEC,RemIntServer
  876.         move.w    #$0003,d0        ;keyboard interrupt
  877.         lea    CIAA_Server(pc),a1
  878.         CALL    EXEC,RemIntServer
  879.         lea    Flags(pc),a0
  880.         st    Flag_60Hz(a0)
  881.         BSR    PatchSystem
  882.         BSR.S    RemoveRomTag
  883.         move.l    d0,d2
  884.         CALL    EXEC,Enable
  885.         rts
  886. ;========================================================================
  887. RemoveRomTag    lea    MyPortName(PC),a1
  888.         CALL    EXEC,FindPort        ;find my port
  889.         tst.l    d0
  890.         bne.s    FoundPort
  891.         moveq    #-1,d0            ;no port found ??
  892.         rts
  893.  
  894. FoundPort    move.l    d0,a4            ;a4 = pointer to MyPort
  895.         move.l    a4,a1
  896.         CALL    EXEC,RemPort        ;remove it !
  897.  
  898.         lea    Flags(pc),a0
  899.         tst.b    Flag_Resident(a0)
  900.         beq.s    FreeMemory
  901.  
  902.         CALL    EXEC,Forbid        ;shut down system
  903.         CALL    EXEC,Disable
  904.  
  905.         lea    MyMemList-MyPort(a4),a1    ;find my memlist
  906.         lea    KickMemPtr(a6),a0
  907. FindMyMemList    move.l    LN_SUCC(a0),d0
  908.         cmp.l    d0,a1
  909.         beq.s    FoundMyList
  910.         move.l    d0,a0
  911.         bra.s    FindMyMemList
  912.  
  913. FoundMyList    move.l    LN_SUCC(a1),d0        ;clear memlist from system
  914.         move.l    d0,LN_SUCC(a0)        ; LN_SUCC = 0, so this also
  915.                         ; works for KickMemPtr
  916.  
  917.         move.l    RomTagPtrs-MyPort+4(a4),KickTagPtr(a6)
  918.         beq.s    NoSecondTag
  919.         bclr    #7,KickTagPtr(a6)    ;clear bit 31
  920.  
  921. NoSecondTag    CALL    EXEC,SumKickData
  922.  
  923.         tst.l    KickTagPtr(a6)        ;check if one of the
  924.         bne.s    .Set            ;ptrs is set
  925.         tst.l    KickMemPtr(a6)        ;if so, then no need
  926.         bne.s    .Set            ;to calc checksum
  927.         clr.l    d0            ;so, clear it !
  928.  
  929. .Set        move.l    d0,KickCheckSum(a6)    ;restore old 
  930.  
  931.         CALL    EXEC,Enable        ;power up system
  932.         CALL    EXEC,Permit
  933.  
  934. FreeMemory    lea    TagCode-MyPort(a4),a1    ;free tag memory
  935.         move.l    #TagCodeLen,d0
  936.         CALL    EXEC,FreeMem
  937.  
  938.         clr.l    d0
  939.         rts
  940.  
  941. ;========================================================================
  942. CIAA_Server    DC.L    0            ;interrupt server structure
  943.         DC.L    0
  944.         DC.B    2            ;type = interrupt
  945.         DC.B    10            ;pri
  946.         DC.L    ProjectName-TagCode
  947.         DC.L    CIAA_Server-TagCode
  948.         DC.L    CIAA_Server_Int-TagCode
  949.  
  950. CIAB_Server    DC.L    0
  951.         DC.L    0
  952.         DC.B    2            ;type = interrupt
  953.         DC.B    10            ;pri
  954.         DC.L    ProjectName-TagCode
  955.         DC.L    CIAB_Server-TagCode
  956.         DC.L    CIAB_Server_Int-TagCode
  957.  
  958. VBI_Server    DC.L    0
  959.         DC.L    0
  960.         DC.B    2            ;type = interrupt
  961.         DC.B    127            ;pri
  962.         DC.L    ProjectName-TagCode
  963.         DC.L    VBI_Server-TagCode
  964.         DC.L    VBI_Server_Int-TagCode
  965.  
  966. MyMemList    DS.B    LN_SIZE            ;memlist structure
  967.         DC.W    1
  968.         DC.L    NULL
  969.         DC.L    TagCodeLen
  970.  
  971. MyPort        DC.L    NULL            ;message port structure
  972.         DC.L    NULL
  973.         DC.B    NT_MSGPORT
  974.         DC.B    0
  975.         DC.L    NULL
  976.         DC.B    0
  977.         DC.B    0
  978.         DC.L    NULL
  979.         DS.B    14
  980.  
  981. MyRomTag    DC.W    RTC_MATCHWORD        ;resident structure
  982.         DC.L    NULL
  983.         DC.L    NULL
  984.         DC.B    RTF_COLDSTART
  985.         DC.B    1
  986.         DC.B    0
  987.         DC.B    -10
  988.         DC.L    NULL
  989.         DC.L    NULL
  990.         DC.L    0
  991.  
  992. ;========================================================================
  993. ProjectName    DC.B    "60Hz emulator by P. de Boer",$0
  994. MyPortName    DC.B    "60Hz emulator.port",$0
  995.         EVEN
  996.  
  997. CIABName    DC.B    "ciab.resource",$0
  998. INTName        DC.B    "intuition.library",$0
  999. GFXName        DC.B    "graphics.library",$0
  1000.         EVEN
  1001.  
  1002. NoTimerAlert    DC.W    20
  1003.         DC.B    17
  1004.         DC.B    "Emulator failure: "
  1005.         DC.B    "CIA-B Timer-A already in use !",$0
  1006.         EVEN
  1007.  
  1008. NoResourceAlert    DC.W    20
  1009.         DC.B    17
  1010.         DC.B    "Emulator failure: "
  1011.         DC.B    "Unable to open ciab.resource !",$0
  1012.         EVEN
  1013.  
  1014. StartPos    DC.L    $3202        ;Start pos
  1015. EndPos        DC.W    $0104
  1016.  
  1017. Flags        DCB.B    8
  1018. EnterKeys    DC.L    $FFFFFF00
  1019. VBITime        DC.W    8*45        ;buffer time (important !)
  1020.  
  1021. INTBase        DC.L    0
  1022. CIABBase    DC.L    0
  1023. RomTagPtrs    DCB.L    2,$0
  1024.  
  1025. TagCodeLen    EQU    *-TagCode
  1026.  
  1027. ;========================================================================
  1028. ;|
  1029.